package com.ybear.ybcomponent.widget.linkage.view

import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintLayout
import com.ybear.ybcomponent.widget.linkage.LinkageAnimationHelper
import com.ybear.ybcomponent.widget.linkage.LinkageLayoutParams
import com.ybear.ybcomponent.widget.linkage.effector.base.CoreEffector
import com.ybear.ybcomponent.widget.linkage.enums.ViewLinkage
import com.ybear.ybcomponent.widget.linkage.interfaces.ILinkage
import com.ybear.ybcomponent.widget.linkage.interfaces.OnScrollListener

/**
 * @Author MiWi
 * @Date 2025年2月13日
 * @Description Linkage - 联动器
 *
 * This custom nested scrolling control provides a set of configurable scrolling effects,
 * which can be applied to child views via XML attributes.
 *
 * 功能说明：
 * 下述属性作用域： [LinkageAppBar] 子控件使用。
 *  eg:
 *      <LinkageAppBar>
 *          <ImageView
 *              linkageScroll="zoom" />
 *      </LinkageAppBar>
 *
 * - linkageScroll：用于指定滑动时的联动效果，支持以下枚举值：
 *   - custom (1)：自定义控件行为。
 *   - zoom (2)：控件缩放效果，可实现视图放大或缩小。
 *   - alpha (3)：控件渐变效果，当 alpha 为 1 时控件渐变隐藏，alpha 为 0 时渐变显示。
 *   - extend (4)：控件延伸效果，使控件沿特定方向延展。
 *   - extendRecovery (5)：控件延伸后恢复原状态的效果。
 *   eg: app:linkageScroll="extend"
 *
 * - linkageStartOffset：定义效果开始的起始距离。
 *   - 对于 zoom 效果，默认值为 0，通常设置为负数以指示缩放起点。
 *   - 对于 alpha 效果，如未设置则默认跟随控件自身属性。
 *   - 对于 extend 效果，默认值为 0。
 *   eg: app:linkageStartOffset="0dp"
 *
 * - linkageEndOffset：定义效果终止的距离，对应 zoom、alpha 和 extend 效果的终点。
 *   eg: app:linkageEndOffset="100dp"
 *
 * - linkageBindViewId：当控件的父布局不是 Linkage系列滑动布局 时，
 *   可通过绑定具体的 View ID 来实现联动效果（例如：app:linkageBindViewId="@id/scroll_view"）。
 *   eg: app:linkageBindViewId="@id/scroll_view
 */
open class LinkageAppBar @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
    private var onScrollListener: OnScrollListener? = null
    var linkageLayoutParams: LinkageLayoutParams
        get() {
            val lp = layoutParams
            return if( lp is LinkageLayoutParams ) lp else field
        }

    init {
        linkageLayoutParams = LinkageLayoutParams( context, attrs )
    }

    override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams {
        return LinkageLayoutParams( context, attrs )
    }

    override fun generateLayoutParams(p: ViewGroup.LayoutParams): ViewGroup.LayoutParams {
        return LinkageLayoutParams( p )
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        // 查找父类或者父类同级为 LinkageView 的控件
        findParentLinkageView()?.let { parent ->
            onScrollListener = object : OnScrollListener {
                override fun onScroll(ev: MotionEvent, oldScrollX: Float, oldScrollY: Float) : Boolean {
                    return handleOnScroll( parent, ev, this@LinkageAppBar )
                }
            }.apply {
                getHelper( parent )?.addOnScrollListener( this )
            }
        }
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        // 查找父 View 中的 LinkageView 并移除监听器
        onScrollListener?.let {
            getHelper( findParentLinkageView() )?.removeOnScrollListener( it )
        }
    }

    open fun isValidViewMode() : Boolean {
        return linkageLayoutParams.viewLinkage != ViewLinkage.NONE
    }

    open fun restoreEffector() {
        currentEffector?.restoreEffector( false )
    }

    private fun findParentLinkageView(): ViewGroup? {
        // 如果已缓存，则直接返回
        linkageLayoutParams.linkageBindView?.let { cached ->
            if (cached is ILinkage) return cached
        }
        val p = parent
        if( p is ViewGroup && p is ILinkage ) return p
        linkageLayoutParams.let {
            if( it.viewLinkage == ViewLinkage.NONE ) return null
            val id = it.linkageBindViewId
            if( id == 0 || p !is ViewGroup ) return null
            // 查找绑定的布局id
            p.findViewById<ViewGroup>( id )?.let { v ->
                if( v is ILinkage ) {
                    it.linkageBindView = v
                    return v
                }
            }
        }
        return null
    }

//    private fun findParentLinkageView(): ViewGroup? {
//        // 1. 如果已缓存，则直接返回
//        linkageLayoutParams.linkageBindView?.let { cached ->
//            if (cached is ILinkage) return cached
//        }
//
//        // 2. 使用自定义属性绑定方式查找（包含遍历查找）
//        val customResult = run {
//            val params = linkageLayoutParams
//            if (params.viewLinkage == ViewLinkage.NONE) return@run null
//            val targetId = params.linkageBindViewId
//            Log.d("TAG", "LINKAAA -> 自定义属性绑定查找成功：targetId $targetId")
//            if (targetId == 0) return@run null
//            val parentGroup = parent as? ViewGroup ?: return@run null
//
//            // 遍历 parentGroup 及其后代，查找目标 id 对应的 ViewGroup
//            fun searchInGroup(group: ViewGroup): ViewGroup? {
//                // 尝试在当前层级查找
//                group.findViewById<ViewGroup>(targetId)?.let { v ->
//                    if (v is ILinkage) return v
//                }
//                // 继续在子 ViewGroup 中查找
//                for (i in 0 until group.childCount) {
//                    val child = group.getChildAt(i)
//                    if (child is ViewGroup) {
//                        searchInGroup(child)?.let { return it }
//                    }
//                }
//                return null
//            }
//            searchInGroup(parentGroup)?.also { found ->
//                params.linkageBindView = found
//                Log.d("TAG", "LINKAAA -> 自定义属性绑定查找成功：$found")
//            }
//        }
//        if ( customResult != null ) return customResult
//
//        // 3. 遍历父视图链，查找实现 ILinkage 的 ViewGroup
//        var current = parent as? View
//        while (current != null) {
//            if (current is ViewGroup && current is ILinkage) {
//                val bindId = linkageLayoutParams.linkageBindViewId
//                if( bindId != 0 && bindId == current.id ) {
//                    linkageLayoutParams.linkageBindViewId = current.id
//                    linkageLayoutParams.linkageBindView = current
//                    Log.d("TAG", "LINKAAA -> 遍历父视图链查找成功：$current")
//                    return current
//                }
//            }
//            current = current.parent as? View
//        }
//        return null
//    }

    private fun handleOnScroll(
        parent: ViewGroup, ev: MotionEvent, childView: LinkageAppBar? = null
    ) : Boolean {
        // 递归遍历所有子 View
        fun traverseViews(viewGroup: ViewGroup, ev: MotionEvent) : Boolean {
            var firstResult = false
            for (i in 0 until viewGroup.childCount) {
                val child = viewGroup.getChildAt( i )
                if ( child is ViewGroup ) {
                    traverseViews( child, ev )
                } else {
                    val result = handleChildView( parent, ev, child ) // 处理子 View
                    if( i == 0 ) firstResult = result
                }
            }
            return firstResult
        }
        if( childView is LinkageAppBar && childView.isValidViewMode() ) {
            return handleChildView( parent, ev, childView )
        }
        // 如果 parent 是一个 LinkageAppBar，并且属性定义了viewMode，则不处理包裹的控件
        val firstChild = parent.getChildAt( 0 )
        if ( firstChild is LinkageAppBar) {
            // 如果第一个子 View 是 LinkageAppBar，则调用其 handlerTouchEvent 方法
            // 直接返回，避免后续处理
            return handleOnScroll( firstChild, ev )
        }

        // 如果第一个子 View 不是 LinkageAppBar，则遍历所有子 View 并处理动画
        if ( firstChild is ViewGroup ) {
            return traverseViews( firstChild, ev )
        } else if (firstChild != null) {
            return handleChildView( parent, ev, firstChild )
        }
        return false
    }

    private var currentEffector: CoreEffector? = null
    private fun handleChildView(parent: ViewGroup, ev: MotionEvent, child: View) : Boolean {
        val helper = getHelper( parent )

        var lp = child.layoutParams as? LinkageLayoutParams
        if( lp == null && child is LinkageAppBar) lp = child.linkageLayoutParams
        val linkage = lp?.viewLinkage ?: helper?.coreEffector?.onViewLinkage()
        if( linkage == ViewLinkage.NONE ) return false
        val start = lp?.linkageStartOffset ?: 0F
        val end = lp?.linkageEndOffset ?: 0F
        // 获取效果器，如果没有则
        currentEffector = helper?.getEffector( linkage )
        return currentEffector
            ?.bindParent( parent )
            ?.bindMotionEvent( ev )
            ?.bindChildView( child )
            ?.buildEffector( start, end )
            ?: false
    }

    private fun getHelper(parent: ViewGroup?) : LinkageAnimationHelper? {
        fun asHelper(parent: ViewGroup?) : LinkageAnimationHelper? {
            return if( parent is ILinkage ) parent.getHelper() else null
        }
        // 如果布局为 LinkageAppBar ，则需要获取 LinkageAppBar 父类或者绑定的 LinkageView 获取 Helper
        if( parent is LinkageAppBar) return asHelper( parent.findParentLinkageView() )
        return asHelper( parent )
    }
}